﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace Sripirom.Pattern.UnitTest.Repository.Configuration.Helpers
{
    public static class XmlRepositoryHelper
    {                                           
        public static Guid GetGuid(this XAttribute attribute)
        {
            return new Guid(attribute.Value);
        }

        public static DateTime GetDateTime(this XAttribute attribute)
        {
            return Convert.ToDateTime(attribute.Value);
        }

        public static Boolean GetBoolean(this XAttribute attribute)
        {
            return Convert.ToBoolean(attribute.Value);
        }

        public static Int32 GetInt32(this XAttribute attribute)
        {
            return Convert.ToInt32(attribute.Value);
        }


        public static XElement CreateXElement(this Object obj)
        {
            XElement x = new XElement(obj.GetType().Name);

            foreach (PropertyInfo pi in obj.GetType().GetProperties())
            {
                if (pi.PropertyType != typeof(string)
                    && pi.PropertyType.Name.Equals(typeof(IEnumerable<>).Name))
                {
                    //Type[] types = pi.PropertyType.GetGenericArguments();

                    //MethodInfo method = GetGenericMethod(obj.GetType(), "CreateXElement");
                    //MethodInfo generic = method.MakeGenericMethod(types);
                    XElement collectionElement = new XElement(pi.Name);
                    foreach (var item in ((IEnumerable)pi.GetValue(obj, new object[] { })))
                    {
                        var returnValue = item.CreateXElement();// generic.Invoke(this, new object[] { item });
                        collectionElement.Add(returnValue);
                    }

                    x.Add(collectionElement);
                }
                else x.Add(new XAttribute(pi.Name, pi.GetValue(obj, new object[] { })));

            }

            return x;

        }

        private static MethodInfo GetGenericMethod(Type type, string name)
        {
            var methods = type.GetMethods();
            foreach (var method in methods.Where(m => m.Name == name))
            {
                return method;
            }

            return null;
        }
    }
}
